#ifndef AUTOSETTINGHELP_H
#define AUTOSETTINGHELP_H

#include <QObject>
#include <QString>
#include <functional>
#include <QDebug>
#include <QSettings>


template<typename T, typename U>
class AutoSettingHelper {
public:
    using Callback = std::function<void(const U& newValue)>;

    AutoSettingHelper(T* instance, const QString& key, U defaultValue, Callback callback = nullptr)
        : instance(instance), key_(key), value_(defaultValue) , callback_(callback) {}

    void init(QSettings *settings) {
        settings_ = settings;

        // 读取设置的值，根据模板类型 U 进行相应处理
        if (settings->contains(key_)) {
            QVariant value = settings->value(key_);

            // 尝试将 QVariant 转换为目标类型 U
            if (value.canConvert<U>()) {
                value_ = value.value<U>();
            } else {
                // 如果转换失败，可能是嵌套数据类型，如 QVariantList 或 QVariantMap
                if constexpr (std::is_same<U, QVariantList>::value) {
                    value_ = value.toList();
                } else if constexpr (std::is_same<U, QVariantMap>::value) {
                    value_ = value.toMap();
                } else {
                    save();
                }
            }
        } else {
            // 如果 key 不存在，使用默认构造的值
            save();
            qCritical() << "Setting not find [" << key_ << "] use default :" << value_;
        }
    }

    U get() const {
        return value_;
    }

    operator U() const {
        return value_;
    }

    // 赋值运算符
    AutoSettingHelper& operator=(const U& newValue) {
        set(newValue);
        return *this;
    }

    void set(const U& newValue , bool skipCallback = false) {
        if (value_ != newValue) {
            value_ = newValue;
            QMetaObject::invokeMethod(instance, (key_ + "Changed").toLatin1().data(),
                                     Qt::QueuedConnection);
            // 打印日志
            qInfo() << "Setting" << key_ << "to new value:" << value_;
            if (callback_ && !skipCallback) {
                callback_(newValue);
            }
            save();
        }
    }

    void save() const {
        if (settings_) {
            settings_->setValue(key_, QVariant::fromValue(value_));
            settings_->sync();
        }
    }

    void firsCallback()
    {
        if (callback_) {
            callback_(value_);
        }
    }

    void setCallback(Callback callback) {
        callback_ = callback;
    }

private:
    QSettings *settings_;
    T* instance;
    QString key_;
    U value_;
    const QString configSection_;
    Callback callback_;
};




#define AUTO_SETTING_PROPERTY(className, type, name, defaultValue) \
private: \
    AutoSettingHelper<className, type> m_##name{this, #name, defaultValue}; \
    Q_SIGNALS: \
    void name##Changed(); \
    public: \
    Q_PROPERTY(type name READ name WRITE set##name NOTIFY name##Changed) \
    type name() const { return m_##name.get(); } \
    void set##name(const type &value) { m_##name.set(value); }



#endif // AUTOSETTINGHELP_H
